package com.gzyj.flink.gps.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Pair;
import com.gzyj.flink.gps.mapper.mysql.MapVehareaMapper;
import com.gzyj.flink.gps.mapper.mysql.MapareaMapper;
import com.gzyj.flink.pojo.mysql.set.MapVeharea;
import com.gzyj.flink.pojo.mysql.set.Maparea;
import com.gzyj.flink.utils.PointUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class AreaService {


    public AreaService() {

    }


    public Maparea InChengDuArea(String vehicleId, double lon, double lat, MapVehareaMapper mapVehareaMapper, MapareaMapper mapareaMapper) {
        Maparea areaSetting = null;
        try {
            List<Maparea> areaSettingList = getAreaSettingList(vehicleId, mapVehareaMapper, mapareaMapper);

            if (CollectionUtil.isNotEmpty(areaSettingList)) {
                for (Maparea mySetting : areaSettingList) {
                    if (mySetting.getDeleted()) {
                        continue;
                    }
                    if (mySetting.getBydependency() == 1) {
                        //如果是属地，则跳过
                        continue;
                    }
                    if (mySetting.getBymanor() == 0) {
                        continue;
                    }
                    switch (mySetting.getAreatype()) {
                        case "rect": {
                            try {
                                //矩形'
                                String[] points = mySetting.getGpspoints().split(";");
                                double lLon = Double.valueOf(points[1].split(",")[0]);
                                double lLat = Double.valueOf(points[1].split(",")[1]);
                                double sLon = Double.valueOf(points[3].split(",")[0]);
                                double sLat = Double.valueOf(points[3].split(",")[1]);
                                if (PointUtils.InRectangle(lon, lat,
                                        lLon, lLat, sLon, sLat)) {
                                    areaSetting = mySetting;

                                    return areaSetting;
                                }
                            } catch (Exception e) {
                                areaSetting = null;
                                return areaSetting;
                            }
                        }
                        break;
                        case "polygon":
                        case "govArea":
                        case "route": {
                            //多边形,先判断是否再多边形的大矩形框，再判断多边形
                            if (PointUtils.InRectangle(lon, lat, mySetting.getMaxLongitudeExt(), mySetting.getMaxLatitudeExt(), mySetting.getMinLongitudeExt(), mySetting.getMinLatitudeExt())) {
                                if (PointUtils.InPolygoned(lon, lat,
                                        mySetting.getLonsExt().toArray(new Double[mySetting.getLonsExt().size()]), mySetting.getLatsExt().toArray(new Double[mySetting.getLatsExt().size()]))) {
                                    areaSetting = mySetting;
                                    return areaSetting;
                                }
                            }
                        }
                        break;
                        case "circle": {
                            //圆形'
                            String[] points = mySetting.getGpspoints().split(";");
                            double Lon = Double.valueOf(points[0].split(",")[0]);
                            double Lat = Double.valueOf(points[0].split(",")[1]);
                            if (PointUtils.InCircle(lon, lat,
                                    Lon, Lat, mySetting.getRadius())) {
                                areaSetting = mySetting;
                                return areaSetting;
                            }
                        }
                        break;
                        default:
                            break;
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return null;
        }
    }

    public Maparea InArea(String vehicleId, double lon, double lat, boolean isLimited,MapVehareaMapper mapVehareaMapper,MapareaMapper mapareaMapper) {
        List<Maparea> areaSettingList = getAreaSettingList(vehicleId,mapVehareaMapper,mapareaMapper);
        Maparea areaSetting = null;
        try {
            if (CollectionUtil.isNotEmpty(areaSettingList)) {
                for (Maparea mySetting : areaSettingList) {
                    if (mySetting.getDeleted()) {
                        continue;
                    }
                    if (mySetting.getBydependency() == 1) {
                        //如果是属地，则跳过
                        continue;
                    }
                    if (mySetting.getBymanor() == 1) {
                        continue;
                    }
                    if (isLimited && mySetting.getLimitspeed() == 0) {
                        //如果查限速区域，区域没开限速则跳过
                        continue;
                    }

                    switch (mySetting.getAreatype()) {
                        case "rect": {
                            try {
                                //矩形'
                                String[] points = mySetting.getGpspoints().split(";");
                                double lLon = Double.valueOf(points[1].split(",")[0]);
                                double lLat = Double.valueOf(points[1].split(",")[1]);
                                double sLon = Double.valueOf(points[3].split(",")[0]);
                                double sLat = Double.valueOf(points[3].split(",")[1]);
                                if (PointUtils.InRectangle(lon, lat,
                                        lLon, lLat, sLon, sLat)) {
                                    areaSetting = mySetting;
                                    return areaSetting;
                                }
                            } catch (Exception e) {
                                areaSetting = null;
                                return areaSetting;
                            }
                        }
                        break;
                        case "polygon":
                        case "govArea":
                        case "route": {
                            //多边形,先判断是否再多边形的大矩形框，再判断多边形
                            if (PointUtils.InRectangle(lon, lat, mySetting.getMaxLongitudeExt(), mySetting.getMaxLatitudeExt(), mySetting.getMinLongitudeExt(), mySetting.getMinLatitudeExt())) {
                                if (PointUtils.InPolygoned(lon, lat,
                                        mySetting.getLonsExt().toArray(new Double[mySetting.getLonsExt().size()]), mySetting.getLatsExt().toArray(new Double[mySetting.getLatsExt().size()]))) {
                                    areaSetting = mySetting;
                                    return areaSetting;
                                }
                            }
                        }
                        break;
                        case "circle": {
                            //圆形'
                            String[] points = mySetting.getGpspoints().split(";");
                            double Lon = Double.valueOf(points[0].split(",")[0]);
                            double Lat = Double.valueOf(points[0].split(",")[1]);
                            if (PointUtils.InCircle(lon, lat,
                                    Lon, Lat, mySetting.getRadius())) {
                                areaSetting = mySetting;
                                return areaSetting;
                            }
                        }
                        break;
                        default:
                            break;
                    }


                }
            }
            areaSetting = null;
            return areaSetting;
        } catch (Exception e) {
            areaSetting = null;
            return areaSetting;
        }

    }

    public List<Maparea> getAreaSettingList(String vehicleId, MapVehareaMapper mapVehareaMapper, MapareaMapper mapareaMapper) {
        List<MapVeharea> list = mapVehareaMapper.selectByVehID(vehicleId);

        if (list.size() > 0) {
            List<Maparea> result = mapareaMapper.selectByAreaIds(list.stream().map(e -> e.getAreaid()).collect(Collectors.toList()));

            return result.stream().map(e -> {
                if (e.getAreatype().equalsIgnoreCase("polygon")
                        || e.getAreatype().equalsIgnoreCase("govArea")
                        || e.getAreatype().equalsIgnoreCase("route")) {

                    String[] points = e.getGpspoints().split(";");

                    e.setLonsExt(new ArrayList<>());
                    e.setLatsExt(new ArrayList<>());
                    List<Double> lats = new ArrayList<>();
                    List<Double> lngs = new ArrayList<>();

                    for (String point : points) {
                        lngs.add(Double.valueOf(point.split(",")[0]));
                        lats.add(Double.valueOf(point.split(",")[1]));
                    }
                    e.setLonsExt(lngs);
                    e.setLatsExt(lats);
                    e.setMaxLongitudeExt(Collections.max(e.getLonsExt()));
                    e.setMaxLatitudeExt(Collections.max(e.getLatsExt()));
                    e.setMinLongitudeExt(Collections.min(e.getLonsExt()));
                    e.setMinLatitudeExt(Collections.min(e.getLatsExt()));
                }
                return e;
            }).collect(Collectors.toList());
        } else {
            return new ArrayList<>();
        }

    }

    public Pair<Boolean, Maparea> InRisk(String vehicleId, double lon, double lat, boolean isLimited,MapVehareaMapper mapVehareaMapper,MapareaMapper mapareaMapper) {
        Maparea areaSetting;
        List<Maparea> areaSettingList = getAreaSettingList(vehicleId,mapVehareaMapper,mapareaMapper);
        try {
            if (CollectionUtil.isNotEmpty(areaSettingList)) {
                for (Maparea mySetting : areaSettingList) {
                    if (mySetting.getDeleted()) {
                        continue;
                    }
                    if (mySetting.getBymanor() == 1) {
                        continue;
                    }
                    if (mySetting.getEpidemicrisk() == 0) {
                        //如果不是风险区，则跳过
                        continue;
                    }
                    switch (mySetting.getAreatype()) {
                        case "rect": {
                            try {
                                //矩形'
                                String[] points = mySetting.getGpspoints().split(";");
                                double lLon = Double.valueOf(points[1].split(",")[0]);
                                double lLat = Double.valueOf(points[1].split(",")[1]);
                                double sLon = Double.valueOf(points[3].split(",")[0]);
                                double sLat = Double.valueOf(points[3].split(",")[1]);
                                if (PointUtils.InRectangle(lon, lat,
                                        lLon, lLat, sLon, sLat)) {
                                    areaSetting = mySetting;
                                    return new Pair<>(true, areaSetting);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                areaSetting = null;
                                return new Pair<>(false, areaSetting);
                            }

                        }
                        break;
                        case "polygon":
                        case "govArea":
                        case "route": {
                            //多边形,先判断是否再多边形的大矩形框，再判断多边形
                            if (PointUtils.InRectangle(lon, lat, mySetting.getMaxLongitudeExt(), mySetting.getMaxLatitudeExt(), mySetting.getMinLongitudeExt(), mySetting.getMinLatitudeExt())) {
                                if (PointUtils.InPolygoned(lon, lat,
                                        mySetting.getLonsExt().toArray(new Double[mySetting.getLonsExt().size()]), mySetting.getLatsExt().toArray(new Double[mySetting.getLatsExt().size()]))) {
                                    areaSetting = mySetting;
                                    return new Pair<>(true, areaSetting);
                                }
                            }
                        }
                        break;
                        case "circle": {
                            //圆形'
                            String[] points = mySetting.getGpspoints().split(";");
                            double Lon = Double.valueOf(points[0].split(",")[0]);
                            double Lat = Double.valueOf(points[0].split(",")[1]);
                            if (PointUtils.InCircle(lon, lat,
                                    Lon, Lat, mySetting.getRadius())) {
                                areaSetting = mySetting;
                                return new Pair<>(true, areaSetting);
                            }
                        }
                        break;
                        default:
                            break;
                    }
                }
            }
            //判断是否在区域
            areaSetting = null;
            return new Pair<>(false, areaSetting);
        } catch (Exception e) {
            areaSetting = null;
            return new Pair<>(false, areaSetting);
        }
    }

    public Pair<Boolean, Maparea> InDependency(String vehicleId, double lon, double lat, boolean isLimited,MapVehareaMapper mapVehareaMapper,MapareaMapper mapareaMapper) {
        Maparea areaSetting;
        try {

            List<Maparea> areaSettingList = getAreaSettingList(vehicleId,mapVehareaMapper,mapareaMapper);
            if (CollectionUtil.isNotEmpty(areaSettingList)) {
                for (Maparea mySetting : areaSettingList) {
                    if (mySetting.getDeleted()) {
                        continue;
                    }
                    if (mySetting.getBymanor() == 1) {
                        continue;
                    }
                    if (mySetting.getBydependency() == 0) {
                        //如果不是属地，则跳过
                        continue;
                    }
                    if (mySetting.getByshare() == 1) {
                        //如果是共享区域，则跳过
                        continue;
                    }
                    switch (mySetting.getAreatype()) {
                        case "rect": {
                            try {
                                //矩形'
                                String[] points = mySetting.getGpspoints().split(";");
                                double lLon = Double.valueOf(points[1].split(",")[0]);
                                double lLat = Double.valueOf(points[1].split(",")[1]);
                                double sLon = Double.valueOf(points[3].split(",")[0]);
                                double sLat = Double.valueOf(points[3].split(",")[1]);
                                if (PointUtils.InRectangle(lon, lat,
                                        lLon, lLat, sLon, sLat)) {
                                    areaSetting = mySetting;
                                    return new Pair<>(true, areaSetting);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                areaSetting = null;
                                return new Pair<>(false, areaSetting);
                            }
                        }
                        break;
                        case "polygon":
                        case "govArea":
                        case "route": {
                            //多边形,先判断是否再多边形的大矩形框，再判断多边形
                            if (PointUtils.InRectangle(lon, lat, mySetting.getMaxLongitudeExt(), mySetting.getMaxLatitudeExt(), mySetting.getMinLongitudeExt(), mySetting.getMinLatitudeExt())) {
                                if (PointUtils.InPolygoned(lon, lat,
                                        mySetting.getLonsExt().toArray(new Double[mySetting.getLonsExt().size()]), mySetting.getLatsExt().toArray(new Double[mySetting.getLatsExt().size()]))) {
                                    areaSetting = mySetting;
                                    return new Pair<>(true, areaSetting);
                                }
                            }
                        }
                        break;
                        case "circle": {
                            //圆形'
                            String[] points = mySetting.getGpspoints().split(";");
                            double Lon = Double.valueOf(points[0].split(",")[0]);
                            double Lat = Double.valueOf(points[0].split(",")[1]);
                            if (PointUtils.InCircle(lon, lat,
                                    Lon, Lat, mySetting.getRadius())) {
                                areaSetting = mySetting;
                                return new Pair<>(true, areaSetting);
                            }
                        }
                        break;
                        default:
                            break;
                    }
                }
            }
            //判断是否在区域
            areaSetting = null;
            return new Pair<>(false, areaSetting);
        } catch (Exception e) {
            areaSetting = null;
            return new Pair<>(true, areaSetting);
        }
    }

}
